package com.wanjia.estate.controller;

import cn.hutool.core.img.ImgUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import cn.hutool.json.JSONUtil;
import com.wanjia.estate.pojo.bank.nxbank.ExtAttributesCommonRequest;
import com.wanjia.estate.pojo.bank.nxbank.PayStatus;
import com.wanjia.estate.pojo.bank.nxbank.ZhsdCommonRoot;
import com.wanjia.estate.pojo.bank.nxbank.ZhsdZszf;
import com.wanjia.estate.pojo.model.JsonResult;
import com.wanjia.estate.service.httpservice.NxHttpService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.models.security.SecurityScheme;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;

/**
 * 银联支付控制器
 */
@Tag(name = "银联支付控制器")
@RestController
@RequestMapping("/bank-pay")
@Slf4j
public class BankPayController extends BaseController {

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private BankPayController thisController;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private HttpServletRequest httpServletRequest;

    @Setter(onMethod_ = {@Autowired})
    private NxHttpService nxHttpService;

    @Value("${nsh.test:false}")
    private Boolean nsh;

    @PostMapping("/pay/qr-code")
    @Operation(summary = "获取支付二维码")
    public JsonResult<ZhsdZszf.ZhsdZszfResponse> payQrCode(Integer type) throws Exception {
        String number=null;
        if (type.equals(2)){
            number="55000";
        }else if (type.equals(1)){
            number="8000";
        }
        String channelcode = "947";

        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String formattedDate = currentDate.format(formatter);

        String channeldate = formattedDate;//外围日期
        String channelseq = UUID.randomUUID().toString().replace("-", "").substring(0, 20);
        String traceNo = channelcode + channeldate + channelseq;

        ZhsdZszf.ZhsdZszfRequest request = new ZhsdZszf.ZhsdZszfRequest();
        ZhsdZszf.ZszfRequestService zszfRequestService = new ZhsdZszf.ZszfRequestService();
        ZhsdZszf.ZszfRequestServiceHeader zszfRequestServiceHeader = new ZhsdZszf.ZszfRequestServiceHeader();
        ZhsdZszf.ZszfRequestServiceBody zszfRequestServiceBody = new ZhsdZszf.ZszfRequestServiceBody();
        ZhsdZszf.ZszfRequest zszfRequest = new ZhsdZszf.ZszfRequest();
        zszfRequest.setTerminalUnitno("924314093994471");//商户号
        zszfRequest.setTerminalName("镇江市丹徒不动产登记中心");
        zszfRequest.setTerminalAcctno("");
        zszfRequest.setInmEncDevId("");
        zszfRequest.setFeeflag("");
        zszfRequest.setDiscountrate("");
        zszfRequest.setTransAccFlag("");
        zszfRequest.setSysFlag("1");
        zszfRequest.setMacValue("");
        zszfRequest.setKeyType("");
        zszfRequest.setDeviceId("U1120605");
        zszfRequest.setVersion("");
        zszfRequest.setApiFlag("0");
        zszfRequest.setTransType("1102");//交易类型
        zszfRequest.setMchntCd("924314093994471");
        zszfRequest.setStaffId("0001");//店员号
        zszfRequest.setShopId("924314093994471000");
        zszfRequest.setTraceNo(traceNo);
        if (nsh){
            zszfRequest.setTransAmount("1");//测试交易金额 单位为分
        }else {
            zszfRequest.setTransAmount(number);//交易金额 单位为分
        }
        zszfRequest.setNotifyUrl("");
        zszfRequest.setRemark("OrdinaryRegisterHC");
        zszfRequest.setQrValidTime("360");
        zszfRequest.setOwnerFlag("0");
        zszfRequest.setLongitude("");
        zszfRequest.setLatitude("");
        zszfRequest.setNetworkLicense("");
        zszfRequest.setDeviceType("");
        zszfRequest.setSerialNum("");
        zszfRequest.setEncryptRandNum("");
        zszfRequest.setSecretText("");
        zszfRequest.setAppVersion("");
        zszfRequest.setDeviceIp("");
        ExtAttributesCommonRequest.ExtAttributesRequest extAttributesRequest = new ExtAttributesCommonRequest.ExtAttributesRequest();
        extAttributesRequest.setTemplatecode("000129");
        extAttributesRequest.setTranscode("PUBINC");
        extAttributesRequest.setChannelcode(channelcode);
        extAttributesRequest.setChanneldate(channeldate);
        extAttributesRequest.setChannelseq(channelseq);
        extAttributesRequest.setZoneno("111");
        extAttributesRequest.setBrno("321102024");
        extAttributesRequest.setTellerno("321102024B01");//柜员号
        extAttributesRequest.setTerminalno("321102024B01");//终端号同柜员号
        extAttributesRequest.setChktellerno("");
        extAttributesRequest.setAreacode("3140");
        extAttributesRequest.setItemno("120568");//农商行项目号
        extAttributesRequest.setSubitemno("00");
        extAttributesRequest.setTradeno("001302");
        extAttributesRequest.setChkdate(formattedDate);
        extAttributesRequest.setTellpasswd("");
        extAttributesRequest.setVouchtype("");
        extAttributesRequest.setVouchno("");
        extAttributesRequest.setAbscode("");
        extAttributesRequest.setAbsinfo("");
        extAttributesRequest.setAuthflag("");
        extAttributesRequest.setAuthtellerno("");
        extAttributesRequest.setAuthtellerno2("");
        extAttributesRequest.setAuthpasswd("");
        extAttributesRequest.setPinkeyname("");
        zszfRequestServiceBody.setExtAttributes(extAttributesRequest);
        zszfRequestServiceBody.setRequest(zszfRequest);
        zszfRequestService.setServiceHeader(zszfRequestServiceHeader);
        zszfRequestService.setServiceBody(zszfRequestServiceBody);
        request.setService(zszfRequestService);
        log.debug("request: {}", JSONUtil.toJsonStr(request));
        ZhsdZszf.ZhsdZszfResponse zszf = nxHttpService.zszf(request);
        log.debug("response: {}", zszf);

        if (Optional.ofNullable(zszf)
                .map(ZhsdCommonRoot::getService)
                .map(ZhsdZszf.ZszfResponseService::getServiceHeader)
                .map(ZhsdZszf.ZszfResponseServiceHeader::getServiceResponse)
                .map(ZhsdZszf.ZszfServiceHeaderResponse::getCode)
                .map(code -> Objects.equals(code, "000000"))
                .orElse(false)
        ) {
            Optional<ZhsdZszf.ZszfTransInfo> transInfo = Optional.ofNullable(zszf)
                    .map(ZhsdCommonRoot::getService)
                    .map(ZhsdZszf.ZszfResponseService::getServiceBody)
                    .map(ZhsdZszf.ZszfResponseServiceBody::getResponse)
                    .map(ZhsdZszf.ZszfResponse::getTransInfo);
            transInfo.map(ZhsdZszf.ZszfTransInfo::getQrcodeUrl)
                    .ifPresent(url -> transInfo.get()
                            .setQrcodeUrl(QrCodeUtil.generateAsBase64(url, QrConfig.create(), "png")));
        }

        return new JsonResult<>(200, zszf);
    }

    @GetMapping("/pay/result")
    @Operation(summary = "支付结果查询")
    public JsonResult<PayStatus.PayStatusResponse> payResult(String traceNo) throws Exception {
        String channelcode = "947";

        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String formattedDate = currentDate.format(formatter);
        String channeldate = formattedDate;
        String channelseq = UUID.randomUUID().toString().replace("-", "").substring(0, 20);

        PayStatus.PayStatusRequest request = new PayStatus.PayStatusRequest();
        PayStatus.PayStatusRequestService payStatusRequestService = new PayStatus.PayStatusRequestService();
        PayStatus.PayStatusRequestServiceHeader payStatusRequestServiceHeader = new PayStatus.PayStatusRequestServiceHeader();
        PayStatus.PayStatusRequestServiceBody payStatusRequestServiceBody = new PayStatus.PayStatusRequestServiceBody();
        PayStatus.PayStatusRequestBody payStatusRequest = new PayStatus.PayStatusRequestBody();
        payStatusRequest.setTerminalUnitno("924314093994471");
        payStatusRequest.setTerminalName("镇江市丹徒不动产登记中心");
        payStatusRequest.setTerminalAcctno("");
        payStatusRequest.setInmEncDevId("");
        payStatusRequest.setFeeflag("");
        payStatusRequest.setDiscountrate("");
        payStatusRequest.setTransAccFlag("");
        payStatusRequest.setSysFlag("1");
        payStatusRequest.setMacValue("");
        payStatusRequest.setKeyType("");
        payStatusRequest.setDeviceId("U1120605");
        payStatusRequest.setVersion("");
        payStatusRequest.setApiFlag("0");
        payStatusRequest.setTransType("1104");
        payStatusRequest.setMchntCd("924314093994471");
        payStatusRequest.setStaffId("0001");
        payStatusRequest.setTraceNo(traceNo);//唯一
        payStatusRequest.setLongitude("");
        payStatusRequest.setLatitude("");

        ExtAttributesCommonRequest.ExtAttributesRequest extAttributesRequest = new ExtAttributesCommonRequest.ExtAttributesRequest();
        extAttributesRequest.setTemplatecode("000129");
        extAttributesRequest.setTranscode("PUBINC");
        extAttributesRequest.setChannelcode(channelcode);//渠道号
        extAttributesRequest.setChanneldate(channeldate);//渠道日期
        extAttributesRequest.setChannelseq(channelseq);//渠道流水
        extAttributesRequest.setZoneno("111");
        extAttributesRequest.setBrno("321102024");
        extAttributesRequest.setTellerno("321102024B01");
        extAttributesRequest.setTerminalno("321102024B01");
        extAttributesRequest.setChktellerno("");
        extAttributesRequest.setAreacode("3140");
        extAttributesRequest.setItemno("120568");
        extAttributesRequest.setSubitemno("00");
        extAttributesRequest.setTradeno("001302");
        extAttributesRequest.setChkdate(formattedDate);
        extAttributesRequest.setTellpasswd("");
        extAttributesRequest.setVouchtype("");
        extAttributesRequest.setVouchno("");
        extAttributesRequest.setAbscode("");
        extAttributesRequest.setAbsinfo("");
        extAttributesRequest.setAuthflag("");
        extAttributesRequest.setAuthtellerno("");
        extAttributesRequest.setAuthtellerno2("");
        extAttributesRequest.setAuthpasswd("");
        extAttributesRequest.setPinkeyname("");
        payStatusRequestServiceBody.setExtAttributes(extAttributesRequest);
        payStatusRequestServiceBody.setRequest(payStatusRequest);
        payStatusRequestService.setServiceHeader(payStatusRequestServiceHeader);
        payStatusRequestService.setServiceBody(payStatusRequestServiceBody);
        request.setService(payStatusRequestService);
        log.info("request: {}", JSONUtil.toJsonStr(request));
        PayStatus.PayStatusResponse payStatus = nxHttpService.payStatus(request);
        log.info("response: {}", JSONUtil.toJsonStr(payStatus));
        return new JsonResult<>(200, payStatus);
    }
}
